#!/usr/bin/env python
# -*- coding: utf-8 -*-


import base64

import time

from random import randint
from functools import partial
import json
import requests
import logging
_logger = logging.getLogger(__name__)


def get_random_password(login):
    # 加密算法,通过 login 计算密码
    #
    psw = str(base64.b64encode(login.encode("utf-8")), encoding="utf-8")
    return psw

    # s1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    # s2 = 'abcdefghijklmnopqrstuvwxyz'
    # s3 = '0123456789'
    # s4 = '!@$^&*_+-|:<>'
    # ss = s3 + s1 + s3 + s2 + s3 + s4 + s3
    # return ''.join([ss[randint(0, len(ss)-1)] for i in range(randint(10, 16))])


def ret(r):
    print('status_code:', r.status_code)
    print('raw:', r.raw.read())
    print('content:', r.content)
    #print ('text:', r.text)
    print('headers:', r.headers)


# print('t1')
# t1()

def jsonrpc(uri, data=None, params=None, sid=None, client=None):
    headers = {"content-type": "application/json"}
    data1 = {"jsonrpc": "2.0",
             "method": "call",
             "id": 123,
             "params": data and data or {}
             }

    params1 = params and params.copy() or {}
    if sid:
        #params1.update( {'session_id':sid} )
        headers.update({'X-Openerp-Session-Id': sid})

    if not client:
        client = requests

    rspd = client.post(uri, params=params1,
                       data=json.dumps(data1),
                       headers=headers)
    # print rspd
    # ret(rspd)

    content = json.loads(rspd.content)
    res = content.get('result', {})

    error = content.get('error', {})

    if error:
        print(uri, data, sid)
        print(error)

        return None

    return json.loads(rspd.content).get('result', {})


class RPC(object):
    def __init__(self, host, db):
        self.host = host
        self.db = db
        self.sid = None

    def t1(self):
        headers = {"content-type": "application/json",
                   "credentials": "include"}
        uri = self.host + '/api/test1'
        params = {}
        data = {}
        rspd = requests.post(uri, params=params,
                             data=json.dumps(data),
                             headers=headers)

        ret(rspd)

    def login(self, user, psw):
        url = self.host + '/api/login'

        try:
            result = jsonrpc(
                url, {'db': self.db, 'login': user, 'password': psw})
            self.sid = result.get('session_id')

            return result

        except Exception as e:
            _logger.warning('Error connect server, %s' % str(e))

            return None

    def call_api(self, url, **kw):
        url = self.host + url
        kw2 = {
            'db': self.db
        }
        kw2.update(kw)
        result = jsonrpc(url, kw2, sid=self.sid)
        return result

    def execute(self, model, method, *args, **kwargs):
        print('xxxxx, args, kwargs', model, method, args, kwargs)

        URI_API = self.host + '/api/call'
        return jsonrpc(URI_API, {'model': model, 'method': method,
                                 'args': args, 'kwargs': kwargs}, sid=self.sid)

    def t2(self, url, model=None):
        headers = {"content-type": "application/json",
                   "credentials": "include"}
        uri = self.host + url
        params = {}
        data = {
            'params': {
                'model': model,
                'fields': ['name']
            }
        }

        rspd = requests.get(uri, params=params,
                            data=json.dumps(data),
                            headers=headers)

        ret(rspd)


class Model(object):
    def __init__(self, model, odoo):
        self.model = model
        self.odoo = odoo
        self.rpc = odoo.rpc
        self.env = odoo.env

    def __getattr__(self, attr):
        # print(attr)
        return partial(self.rpc.execute, self.model, attr)

    def rpc_search_one(self, domain):
        res = self.search(domain, limit=1)
        if res:
            return res[0]
        else:
            return None

    def rpc_find_or_create(self, domain, values):
        res = self.search(domain, limit=1)
        if res:
            return res[0]
        res = self.create(values)
        return res

    def rpc_update_or_create(self, domain, values):
        res = self.search(domain, limit=1)
        if res:
            self.write(res, values)
            return res[0]

        res = self.create(values)
        return res


class IotGateway(Model):
    def get_by_code(self, code):
        res = self.rpc_find_or_create([('code', '=', code)], {
            'code': code,
            'name': code,
            'user_id': None
        })
        return res

    def get_user(self, login, password, gateway_id):
        User = self.env['res.users']
        res = User.rpc_update_or_create([('login', '=', login)], {
            'login': login,
            'name': login,
            'email': login,
            'password': password,
            'related_gateway_id': gateway_id
        })

        return res

    def regsiter(self, code):
        print(' reg gtw,', code)
        gateway_id = self.get_by_code(code)
        login = 'user_for_gateway_' + code
        password = get_random_password(login)
        # print( 'password: ', password)
        user_id = self.get_user(login, password, gateway_id)
        # print( 'user_id: ', user_id)

        return {
            'gateway_id': gateway_id,
            'related_user_id': user_id,
            'code': code,
            'user': login,
            'password': password
        }


class IotDevice(Model):
    def get_by_code(self, code):
        res = self.rpc_find_or_create([('code', '=', code)], {
            'code': code,
            'name': code,
            'user_id': None
        })
        return res

    def find_sensor_type(self, code):
        Device = self.env['iot.sensor.type']
        res = Device.search([('code', '=', code)])
        return res and res[0] or None

    def find_sensor(self, device_id, sensor_type_id, rec):
        Device = self.env['iot.sensor']
        device_code = rec['device_code']
        sensor_code = rec['sensor_code']
        code = '%s-%s' % (device_code, sensor_code)

        res = Device.rpc_update_or_create([('code', '=', code)], {
            'code': code,
            'name': code,
            'device_id': device_id,
            'sensor_type_id': sensor_type_id
        })
        return res

    def regsiter(self, rec):
        print(' reg dev,', rec)
        device_id = self.get_by_code(rec['device_code'])
        sensor_type_id = self.find_sensor_type(rec['sensor_type'])
        sensor_id = self.find_sensor(device_id, sensor_type_id, rec)

        return {
            'device_id': device_id,
            'sensor_id': sensor_id,
            'sensor_type_id': sensor_type_id,
            'device_code': rec['device_code'],
            'sensor_code': rec['sensor_code'],
            'sensor_type': rec['sensor_type'],
        }


class Env(object):
    def __init__(self, odoo):
        self.odoo = odoo
        self._env = {
            'iot.gateway': IotGateway,
            'iot.device': IotDevice

        }

    def __getitem__(self, index):
        # print(index)
        return (self._env.get(index) or Model)(index, self.odoo)


class ODOO(object):
    def __init__(self, host, db):
        self.rpc = RPC(host, db)
        self.env = Env(self)
        self.session_id = False

    def login(self, user, psw):
        result = self.rpc.login(user, psw)
        self.session_id = result and result.get('session_id')
        return self.session_id

    def call_api(self, url, **kw):
        result = self.rpc.call_api(url, **kw)
        return result

    def get_now(self):
        if self.session_id:
            # 如果有网络, 此时 树莓派 已经运行有几十秒时长, 时间已经更新了.
            now = time.time()
            now = round(now)
        else:
            now = time.time()
            now = round(now)
            now = 0
        return now


def get_odoo(**options):
    rpi_debug = options.get('rpi_debug')
    rpi_debug = rpi_debug and eval(rpi_debug)

    gatewate_code = options.get('gatewate_code')
    host = options.get('host')
    db = options.get('db')

    user = options.get('user')
    password = options.get('password')
    # print('get odoo, options,gatewate_code:', options, gatewate_code)

    if not user:
        user = 'user_for_gateway_' + gatewate_code
        password = get_random_password(user)

    odoo = ODOO(host, db)
    if not rpi_debug:
        odoo.login(user, password)

    return odoo


def test_1():

    HOST = 'http://192.168.56.101:8069'
    SERVER = 'T2'
    rpc = RPC(HOST, SERVER)

    session_id = 'db9c386675a3db4abc99969d8effc9e4f163e08d'

    url = '/web/dataset/search_read' + '?session_id=' + session_id

    # ss = jsonrpc(url)

    rpc.t2(url, model='res.partner')

    # print(ss)


if __name__ == '__main__':
    pass

    host = 'http://106.13.191.63:8069'
    db = 'TheWell'
    user = 'xxmcu@sohu.com'
    password = '123456'

    odoo = ODOO(host, db)
    res = odoo.login(user, password)
    print(res)

    # Model = odoo.env['iot.gateway']
    # res = Model.search([])
    # print(res)
    # if res:
    #     return res

    # res = Model.create({
    #     'code': uuid,
    #     'name': uuid
    # })
    # print(res)

    # return res


"""
    HOST = 'http://192.168.56.101:8069'
    SERVER = 'T2'
    rpc = RPC(HOST, SERVER)

    user = 'admin'
    psw = '123456'
    result = login(user, psw)
    print ('login:',result)
    
    sid = result.get('session_id')
    print ('sid:',sid)

    print ('14234234234232')

    ptn = execute(sid, 'cr.station','fields_get', [], [] )
    print 'product', ptn.keys()


    print '14234234234232'
    ptn = execute(sid, 'cr.station','search_read', [], ['name','cr_company_ids','section_id'] )
    
    print 'product', len(ptn)
    
    for p in ptn:
        pass
        print p['id'], p['name'], p['cr_company_ids'],p['section_id']


    print '14234234234232'
    ptn = execute(sid, 'cr.section','search_read', [], ['name','cr_company_ids'] )
    
    print 'product', len(ptn)
    
    for p in ptn:
        pass
        print p['id'], p['name'], p['cr_company_ids']

  

"""
